﻿package DCRS::Activity;

use strict;
use warnings;
use base 'CGI::Application';
use Clarion;
use Time::CTime;
use Tie::File::AsHash;
use DateTime::Format::Excel;
use Date::Calc qw(Today_and_Now Delta_YMDHMS Add_Delta_YMDHMS Delta_DHMS Date_to_Text);

# This is where we keep all of the .dat files.
my $DBPATH = '/media/officedb/PUBLIC/OFFICE4/';

# Use this object's methods to format serial dates.
my $dto = DateTime::Format::Excel->new();

# Globals for datetime manipulation.
my $today  = [Today_and_Now()];
my $today_clarion = convert_date_to_clarion();
my $yesterday_clarion = $today_clarion -1;
my $year_clarion  = $today_clarion - 365;
my $localtime = localtime();
my $technames  = get_tech_names();
my $customers = get_customer_list();
my (@opencalls, @closedcalls, @notes, @closedfixes);

#------------------------------------------------------------------------------
sub setup
{
    my $self = shift;
    $self->start_mode('report');
    $self->run_modes(
        report => 'activity_report',
    );
}

sub activity_report 
{
    my $self     = shift;
    my $title    = "DCRS Customer Call Activity Report";
    
    #Get open and closed calls into separate lists
    my $dbh = new Clarion $DBPATH. 'opncall.dat' or 
        die("Cannot open database file: $!");      
    for ( 1 .. $dbh->last_record ) {
        my $r = $dbh->get_record_hash($_);
        next if $r->{_DELETED};
        if ($r->{STATUS} eq 'O') {
            push @opencalls, $r;
        }
        elsif ($r->{STATUS} eq 'C') {
            push @closedcalls, $r;
        }
    }
    
    $dbh->close();
    
    #Get all call notes for previous day
    $dbh = new Clarion $DBPATH. 'callnote.dat' or 
        die("Cannot open database file: $!");
        
    for ( 1 .. $dbh->last_record ) {
        my $r = $dbh->get_record_hash($_);
        next if $r->{_DELETED};
        next if ($r->{NOTEDATE} != $today_clarion - 1);
        push @notes, $r;
    }
    
    $dbh->close();
    
    #Get all closed call fixes for previous day
    $dbh = new Clarion $DBPATH. 'calldtl.dat' or 
        die("Cannot open database file: $!");
        
    for ( 1 .. $dbh->last_record ) {
        my $r = $dbh->get_record_hash($_);
        next if $r->{_DELETED};
        next if ($r->{FIN_DATE} != $today_clarion -1);
        push @closedfixes, $r;
    }
    
    $dbh->close();
    
    #for each tech number in service (2-9, excepting VT, find yesterday's notes)
    my @output;
    foreach my $t (2..9) {
        next if $t == 8; # <<HACK>> not sure why this number does not exist in db 
        
        my @open_activity;
        
        my %opencallrow; 
        foreach my $o (@opencalls) {
            my @callnotes = ();
            if ($t == $o->{DSP_TO}) {                                    
                foreach my $n (@notes) {
                    my %noterow = {};
                    if ($n->{NUMBER} == $o->{NUMBER} and ($n->{TECH} == $t)) {
                        %noterow = (
                            tech => $technames->{ $n->{TECH} },
                            notedate => $dto->parse_datetime($n->{NOTEDATE} - 36161 )->mdy("/"),
                            notetime => convert_clarion_time_to_ampm( $n->{NOTETIME} ),
                            comments => ucfirst( join( ' ', split( ' ', $n->{COMMENTS} )))
                        );
                    }
                    if (%noterow) {
                      push @callnotes, \%noterow;  
                    }
                    
                }
                %opencallrow = (
                    number => $o->{NUMBER},
                    time => convert_clarion_time_to_ampm( $o->{TIME} ),
                    dsp_to => $technames->{$t},
                    date => $dto->parse_datetime($o->{DATE} - 36161 )->mdy("/"),
                    name => $customers->{join(":", $o->{CUST_NO}, $o->{CUST_SUB})} || "Not Found",
                    cust_no => $o->{CUST_NO},
                    cust_sub => $o->{CUST_SUB},
                    comment => join(" ", split(" ", $o->{COMMENT})),
                    notes => \@callnotes
                );
            }
        push @open_activity, \%opencallrow; 
        }
              
        my @closed_activity;
  
        foreach my $c (@closedcalls) {
            my %closedrow;
            if ($t == $c->{DSP_TO}) {
                foreach my $f (@closedfixes) {
                    if ($f->{NUMBER} == $c->{NUMBER}) {
                        %closedrow = (
                            number => $c->{NUMBER},
                            name => join(":", $c->{CUST_NO}, $c->{CUST_SUB}),
                            comment => join(" ", split(" ", $c->{COMMENT})),
                            prob_fix => join(" ", split(" ", $f->{PROB_FIX}))
                        );
                    push @closed_activity, \%closedrow;    
                    }
                }
            }           
        }
        
        my %row = (
            techname => $technames->{$t},
            open_activity => \@open_activity,
            closed_activity => \@closed_activity,
        );
        push @output, \%row;
    }
    
    #Create the template 
    my $template = $self->load_tmpl(
        'call/callactivity.tmpl',
        global_vars       => 1,
        loop_context_vars => 1,
        die_on_bad_params => 0
    ); 
    
    $template->param( output => \@output );
    $template->param( title => $title );
    $template->param( localtime => $localtime );
    
    return $template->output;
}

sub get_tech_names 
{
    # Build a hash of all techs using their assigned technumber as the key
    my %tech_names;
    my $dbh   = new Clarion $DBPATH. 'svtech.dat';
    for ( 1 .. $dbh->last_record ) {
        my @r = $dbh->get_record( $_, 'NUMBER', 'NAME' );
        next if $r[0];
        $tech_names{ $r[1] } = $r[2];
    }
    
    $dbh->close();
    return \%tech_names;
}

sub get_customer_list
{
    my %customer_list;
    my $dbh = new Clarion $DBPATH. 'custmr.dat';
    for (1 .. $dbh->last_record) {
        my @r = $dbh->get_record($_, 'NUMBER', 'SUB', 'NAME');
        next if $r[0];
        # Use account number and sub for key
        $customer_list{join(":", $r[1], $r[2])} = $r[3];
    }
    $customer_list{'all:all'} = '- Search All Accounts -';
    
    $dbh->close();
    return \%customer_list;
}

sub get_support_codes 
{
    # These are lables for our customer support status codes.
    my %supcodes = (
        O  => 'On Site',
        D  => 'Depot',
        N  => 'No Support',
        P  => 'SW/Helpdesk',
        R  => 'Rental',
        L  => 'Loaner',
        MA => 'Major Account',
        WK => 'Weekday',
        WW => 'Warranty Weekday',
        WD => 'Warranty Depot',
        WO => 'Warranty Onsite'
    );
    return \%supcodes;
}
sub convert_date_to_clarion 
{
    # Takes the mdy values from localtime
    # and convert to Clarion long format date.
    my ($dt, $f);
    my @f = (localtime)[3 .. 5];    # grabs day/month/year values
    $dt = DateTime->new(
            year => $f[2] + 1900, month => $f[1] + 1, day => $f[0]);
            
    return (DateTime::Format::Excel->format_datetime($dt) + 36161);
}

sub convert_clarion_time_to_ampm
{
    # Takes time value, serialized by number of seconds in 24 hour period.
    # Converts the serial time to human readable time.
    my $t = shift;
    my ($hour, $minute, $rtime, $am_pm, $open_time);
    $rtime  = ($t - 1) / 100;
    $hour   = $rtime / 3600;
    $minute = $rtime % 3600 / 60;
    $hour   = strftime(localtime($hour));
    $minute = strftime(localtime($minute));
    $am_pm  = 'am';
    $hour >= 12  and $am_pm  = 'pm';          # 12-23 are afternoon
    $hour > 12   and $hour   = $hour - 12;    # 13-23 ==> 1-11 (PM)
    $hour == 0   and $hour   = 12;            # convert first hour
    $minute < 10 and $minute = "0$minute";    # "5" ==> "05", etc.

    return "$hour:$minute$am_pm";
}
1;